<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>

  <script>


    // const p = new Promise (() => { // 执行器是同步执行的
    //   /* setTimeout(() => {
    //     // 发ajax
    //     xhr.send()
    //   }, 0); */
    //   // 发ajax    2s
    //   xhr.send()
    // })

    // setTimeout(() => {
    //   p.then((value) => {

    //   })
    // }, 2100);


    /* const p = new Promise((resolve, reject) => { // 执行器同步执行的
      // 发请求去
      axios.get()  // 2S
      // 请求成功后
      resolve(response)
    })

    setTimeout(() => {
      p.then(response => {

      })
    }, 2100); */

 
    // 指定回调
    // 想先指定回调, 后发请求?   在定时器中发请求
    // 想在请求结束后,再指定回调?  在定时器中调用then
    

    /* 
    then():
      1. 指定回调函数来读取/得到成功/失败的结果数据
      2. 返回一个新的promise => 为了封装then指定的回调函数中的任务
        它的结果状态由什么决定?
        由then指定并执行回调函数执行的结果决定
        - 抛出错误 => 失败且reason就是抛出的错误
        - 返回失败的promise => 失败且reason是返回的promise的reason
        - 返回成功的promise => 成功且value是返回的promise的value
        - 返回其它任何值 => 成功且value是返回的值
        - 返回pending的promise => pending的promise

      理解: then为什么要设计返回值为一个新的promise?
          我们可能会在then指定的回调中执行新的任务, 对应的就是返回的新的promise
    */

    /* new Promise((resolve, reject) => {
      // 执行异步任务
      // 如果成功了, 调用resolve
      // 如果失败了, 调用reject
      // resolve(1)
      reject(2)
    }).then(
      value => {
        console.log('onResolved1', value)

      },
      reason => {
        console.log('onRejected1', reason)
        // 在此执行新的任务
        // - 抛出错误 => 失败且reason就是抛出的错误
        // throw 3

        // - 返回失败的promise => 失败且reason是返回的promise的reason
        // return Promise.reject(4)

        // - 返回成功的promise => 成功且value是返回的promise的value
        // return new Promise((resolve) => {
        //   setTimeout(() => {
        //     resolve(5)
        //   }, 2000);
        // })

        // - 返回其它任何值 => 成功且value是返回的值
        // return 6
        // return undefined

        // - 返回pending的promise => pending的promise
        return new Promise(() => {})
      }
    ).then(
      value => {
        console.log('onResovled2222', value)
      },
      reason => {
        console.log('onRejected2222', reason)
      },
    ) */

    /* 
    Promise.all()
    */
    /* function ajax(url) {
      return axios.get(url)
    }
    const p1 = ajax(url1)
    const p2 = ajax(url2)
    const p3 = ajax(url3)
    Promise.all([p1, p2, p3])
      .then(
        responses => { // 得到包含3个成功数据的response的数组
          return ajax(url4)
          // return undefined
        }
      ).then(response4 => {  // 第4个请求成功的回调

      }).catch(error => { // 只要有一个失败了

      }) */

    /* 
    1. 哪里用await: 一般在结果为promise的表达式左侧
        如果await 右侧表达式结果不是promise, 直接得到这个结果
    2. 哪里用async: 离await最近的函数定义的左侧

    成功的value: await左侧以级下面的代码都是在成功之后执行(相当于在成功的回调中执行)
    失败的reason: 使用try...catch中在失败后执行(相当于在失败的回调中执行)

    调用async函数的得到是一个promise对象, promise的结果由aysnc函数体执行的结果决定(与.then类似)

     */

    /* 
    async函数执行返回一个promise
    promse的状态由 async函数体执行的结果 决定    ==> 与then返回的promise类似
    await下面的代码是在成功的回调中执行
    catch下的代码是在失败的回调中执行

    async函数返回的promise的结果状态由什么决定?  由async函数体执行的结果决定
    */
    const getProduct = async () => {
      try {
        const response = await axios.get('/1_js基础/product2.json')
        console.log(response.data)

        return response.data
      } catch (error) {
        console.log(error.message)
        throw error
      }
    }

    function getProduct2() {
      return axios.get('/1_js基础/product2.json').then(
        response => {
          console.log(response.data)
        },
        error => {
          console.log(error.message)
        }
      )
    }

    function test() {
      const result = getProduct()
      console.log(result)
    }

    test()

    // catch的本质是then(value => value, 失败回调)
    // 如果调用.catch是一个成功的promise, 那catch返回的promise是成功的, value不变
    Promise.resolve(1)
    // .then(value => value, reason => {
    //   console.log('11111', reason)
    // })
    .catch(reason => {
      console.log('11111', reason)
    })
    .then(value => {
      console.log('22222', value)
    }, reason => {
      console.log('33333', reason)
    })

    // 如果给成功的promise通过.then只指定了成功的回调, then返回的promise还是失败的, reason不变
    Promise.reject(2)
    .then(value => {

    }, reason => {throw reason})
    .then(value => {

    })
    .catch(reason => {

    })
   

  </script>
</body>
</html>